#define once
#include"Log.hpp"
#include"Mutex.hpp"
#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<errno.h>
#include<stdlib.h>
#include<string>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>


using namespace LogModel;
namespace UdpserverMod
{
    // #define Die(i) exit(i); 
    const static uint16_t PORT=8888;
    const static int defaultsize=1024;
    class Udpserver
    {
        public:
        Udpserver(uint16_t port=PORT):_sockfd(-1),_port(port),_isrunning(false)
        {

        }
        void Initserver()
        {
            //1 创建socket
            _sockfd=socket(AF_INET, SOCK_DGRAM,0);
            if(_sockfd<0)
            {
                LOG(LgoLevel::TATAL)<<"socket"<<strerror(errno);
                exit(1);
            }
            LOG(LgoLevel::INFo)<<"socket is"<<_sockfd;
            //2 填充网络信息并bind
            sockaddr_in sock;
            bzero(&sock,sizeof(sock));
            sock.sin_family=AF_INET;
            sock.sin_port=::htons(_port);
            sock.sin_addr.s_addr=INADDR_ANY;
            int r=::bind(_sockfd,(struct sockaddr*)&sock ,sizeof(sock));
            if(r<0)
            {
                LOG(LgoLevel::TATAL)<<"bind"<<strerror(errno);
                exit(2);
            }
            LOG(LgoLevel::INFo)<<"bind ";

        }
        void Start()
        {
            _isrunning=true;
            while (true)
            {
                char buf[defaultsize];
                struct sockaddr_in peer;
                socklen_t len=sizeof(peer);


                ssize_t n=::recvfrom(_sockfd,buf,sizeof(buf)-1,0,(struct sockaddr *)&peer,&len);
    
                if(n>0)
                {
                    // 消息内容 and 谁发送的
                
                    uint16_t clientport =::ntohs(peer.sin_port);
                    std::string clientip=::inet_ntoa(peer.sin_addr);
                    buf[n]=0;
            
                    
                    std::string clientinfo=std::to_string(clientport)+":"+clientip+":"+buf;

                    LOG(LgoLevel::DEBUG)<<"start"<<clientinfo;

                    std::string echo_string ="echo#";
                    echo_string+=buf;
               
                    
                    ::sendto(_sockfd,echo_string.c_str(),echo_string.size(),0,(struct sockaddr*) &peer,sizeof(peer));
               

                }
                
            }
            _isrunning=false;
            
        }
        ~Udpserver()
        {
            
        }

        private:
        int _sockfd;
        uint16_t _port;//服务器端未来的端口号
        std::string _ip;//服务器所对应的IP-IOPO
        bool _isrunning;//服务器运行状态
    };

}
